package org.nfyszny.zzzs.modules.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;


import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserDepart;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysUserDepartService;
import org.jeecg.modules.system.service.ISysUserService;
import org.nfyszny.zzzs.modules.constant.CertificateConstant;
import org.nfyszny.zzzs.modules.constant.ExamineConstant;
import org.nfyszny.zzzs.modules.constant.ReCordConstant;
import org.nfyszny.zzzs.modules.entity.*;
import org.nfyszny.zzzs.modules.mapper.ZzzsProductRecordingMapper;
import org.nfyszny.zzzs.modules.service.*;
import org.nfyszny.zzzs.modules.utils.UserUtils;
import org.nfyszny.zzzs.modules.vo.RetroactiveAccountabilityVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Description: 产品备案
 * @Author: jeecg-boot
 * @Date: 2022-11-11
 * @Version: V1.0
 */
@Service
public class ZzzsProductRecordingServiceImpl extends ServiceImpl<ZzzsProductRecordingMapper, ZzzsProductRecording> implements IZzzsProductRecordingService {
    @Autowired
    private ISysDepartService departService;
    @Autowired
    private ISysUserDepartService userService;
    @Autowired
    private ISysUserService uService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    @Lazy
    private IZzzsExamineService examineService;
    @Autowired
    private IZzzsCertificateService certificateService;
    @Autowired
    private IZzzsVisualInformationService visualInformationService;
    @Autowired
    private IZzzsBasicInfoService basicInfoService;
    @Autowired
    private IZzzsManagementOfSowingService sowingService;
    @Autowired
    private IZzzsManagementOfHarvestService harvestService;
    @Autowired
    private IZzzsFertilizationManagementService fertilizationManagementService;
    @Autowired
    private IZzzsDosingManagementService dosingManagementService;
    @Autowired
    private IZzzsPestAndDiseaseControlService diseaseControlService;
    @Autowired
    private IZzzsRecordEnterpriseService recordEnterpriseService;
    @Autowired
    @Lazy
    private IZzzsRecordingOfProductionCapacityService capacityService;
    @Autowired
    @Lazy
    private IZzzsRecordOfSupplyAbilityService supplyAbilityService;


    @Override
    public List<ZzzsProductRecording> getListInfo() {

        QueryWrapper<ZzzsProductRecording> queryWrapper = new QueryWrapper<>();
        LoginUser userInfo = UserUtils.getUserInfo();
        queryWrapper.eq("sys_org_code", userInfo.getOrgCode());

        List<ZzzsProductRecording> zzzsProductRecordings = baseMapper.selectList(queryWrapper);
        //过滤掉没有产品证书的产品
        List<ZzzsProductRecording> collect = zzzsProductRecordings.stream().filter(item -> {
            return certificateService.getStatus(item.getId(), false);
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public void saveProductRecordInfo(ZzzsProductRecording zzzsProductRecording) {

        //设置是否是迭代数据和备案状态
        zzzsProductRecording.setIsLogout(ReCordConstant.iterationEnum.LOGOUT_YES.getCode());
        zzzsProductRecording.setStatus(ReCordConstant.RecordEnum.RECORD_CREATE.getCode());
        baseMapper.insert(zzzsProductRecording);

    }

    @Override
    public IPage<ZzzsProductRecording> getListByCompanyId(QueryWrapper<ZzzsProductRecording> queryWrapper, Page<ZzzsProductRecording> page) {

        LoginUser user= (LoginUser)SecurityUtils.getSubject().getPrincipal();
        LoginUser userInfo = UserUtils.getUserInfo();
        System.out.println("userInfo111 = " + userInfo);
        queryWrapper.eq("sys_org_code", userInfo.getOrgCode());
        Page<ZzzsProductRecording> productRecordingPage = this.page(page, queryWrapper);
        return productRecordingPage;
    }

    @Override
    public IPage<ZzzsProductRecording> getCreateListByCompanyId(QueryWrapper<ZzzsProductRecording> queryWrapper, Page<ZzzsProductRecording> page) {
        LoginUser userInfo = UserUtils.getUserInfo();
        queryWrapper.eq("sys_org_code", userInfo.getOrgCode());
        queryWrapper.eq("status", ReCordConstant.RecordEnum.RECORD_CREATE.getCode());
        Page<ZzzsProductRecording> productRecordingPage = this.page(page, queryWrapper);
        return productRecordingPage;
    }

    /**
     * 查询可以准出申请的产品
     *
     * @param queryWrapper
     * @param page
     * @return
     */
    @Override
    public IPage<ZzzsProductRecording> getExitList(QueryWrapper<ZzzsProductRecording> queryWrapper, Page<ZzzsProductRecording> page) {

        LoginUser userInfo = UserUtils.getUserInfo();
//        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//        System.out.println("我是"+loginUser.getOrgCode());
//        System.out.println("我是"+loginUser.getId());
        queryWrapper.eq("sys_org_code", userInfo.getOrgCode());
        queryWrapper.eq("status", ReCordConstant.RecordEnum.RECORD_SUCCESS.getCode());
        queryWrapper.isNull("exit_status");
        Page<ZzzsProductRecording> productRecordingPage = this.page(page, queryWrapper);
        return productRecordingPage;
    }

    @Override
    public IPage<ZzzsProductRecording> getExitaLL(QueryWrapper<ZzzsProductRecording> queryWrapper, Page<ZzzsProductRecording> page) {

        LoginUser userInfo = UserUtils.getUserInfo();
        queryWrapper.eq("sys_org_code", userInfo.getOrgCode());
        queryWrapper.eq("status", ReCordConstant.RecordEnum.RECORD_SUCCESS.getCode());
        queryWrapper.eq("exit_status", ExamineConstant.ExitStatus.NO_EXIT.getCode()).or().eq("exit_status", ExamineConstant.ExitStatus.YES_EXIT.getCode()).or().eq("exit_status",ExamineConstant.ExitStatus.APPLYING.getCode());

        Page<ZzzsProductRecording> productRecordingPage = this.page(page, queryWrapper);
        return productRecordingPage;
    }

    /**
     * 查询可以审批的准出申请
     *
     * @param queryWrapper
     * @param page
     * @return
     */
    @Override
    public IPage<ZzzsProductRecording> getCanApply(QueryWrapper<ZzzsProductRecording> queryWrapper, Page<ZzzsProductRecording> page) {
        LoginUser userInfo = UserUtils.getUserInfo();
        QueryWrapper<ZzzsExamine> wrapper = new QueryWrapper<ZzzsExamine>();
        if (userInfo != null) {
            if (!userInfo.getUsername().equals("root")) {


                wrapper = new QueryWrapper<ZzzsExamine>()
                        .eq("examine_person", userInfo.getId());
            }
        }
        List<String> collect = examineService.list(wrapper

                .eq("examine_status", ExamineConstant.StatusEnum.CHECK_STATUS.getCode())
                .eq("record_type", ExamineConstant.RecordType.PRODUCT_EXIT.getCode())).stream().map(item -> {
            return item.getRecordId();
        }).collect(Collectors.toList());
        Page<ZzzsProductRecording> productRecordingPage = new Page<>();
        if (collect.size() != 0) {
            queryWrapper.in("id", collect);
            productRecordingPage = this.page(page, queryWrapper);
        } else {
            productRecordingPage.setRecords(new ArrayList<>());
            productRecordingPage.setCurrent(0);
        }


        return productRecordingPage;
    }


    /**
     * 申请准出
     *
     * @param
     */
    @Transactional
    @Override
    public void applyForExit(ZzzsProductRecording zzzsProductRecording) {
        zzzsProductRecording = baseMapper.selectById(zzzsProductRecording.getId());
        zzzsProductRecording.setExitStatus(ExamineConstant.ExitStatus.APPLYING.getCode());
        baseMapper.updateById(zzzsProductRecording);
        //分配审批人
        LoginUser userInfo = UserUtils.getUserInfo();
        SysDepart sysDepart = departService.queryCompByOrgCode(userInfo.getOrgCode());
        List<SysDepart> sysDeparts = departService.queryDeptByPid(sysDepart.getId());

        //找出监管部门
        SysDepart sysDepart1 = sysDeparts.stream().filter(item -> {
            return item.getOrgCategory().equals("3");
        }).findAny().get();
        SysUserDepart user = userService.getUserByDeptId(sysDepart1.getId());


        this.saveOrUpdate(zzzsProductRecording);
        //在审批表中插入记录
        ZzzsExamine zzzsExamine = new ZzzsExamine();
        zzzsExamine.setRecordId(zzzsProductRecording.getId());

        zzzsExamine.setExaminePerson(user.getUserId());
        zzzsExamine.setExamineStatus(ExamineConstant.StatusEnum.CHECK_STATUS.getCode());
        zzzsExamine.setRecordType(ExamineConstant.RecordType.PRODUCT_EXIT.getCode());
        examineService.save(zzzsExamine);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //过期前30分钟基于提醒
        redisTemplate.opsForValue().set(zzzsExamine.getId() + "_" + format.format(new Date()) + "_" + user.getUserId() + "_准出_message", "", 2 * 24 * 60 - 30, TimeUnit.MINUTES);
        redisTemplate.opsForValue().set(zzzsExamine.getId() + "_" + format.format(new Date()) + "_" + user.getUserId() + "_准出_exceed", "", 2, TimeUnit.DAYS);
    }

    /**
     * 准出
     *
     * @param zzzsProductRecording
     */
    @Transactional
    @Override
    public void yesExit(ZzzsProductRecording zzzsProductRecording) {
        zzzsProductRecording = baseMapper.selectById(zzzsProductRecording.getId());
        System.out.println("zzzsCertificate = " + zzzsProductRecording);
        zzzsProductRecording.setExitStatus(ExamineConstant.ExitStatus.YES_EXIT.getCode());
        baseMapper.updateById(zzzsProductRecording);
        ZzzsExamine examine = examineService.getOne(new QueryWrapper<ZzzsExamine>().eq("record_id", zzzsProductRecording.getId())
                .eq("record_type", ExamineConstant.RecordType.PRODUCT_EXIT.getCode()).eq("examine_status", ExamineConstant.StatusEnum.CHECK_STATUS.getCode()));
        examine.setExamineStatus(ExamineConstant.StatusEnum.SUCCESS_STATUS.getCode());
        examineService.updateById(examine);
    }

    /**
     * 不予准出
     *
     * @param zzzsProductRecording
     */
    @Override
    public void noExit(ZzzsProductRecording zzzsProductRecording) {
        zzzsProductRecording = baseMapper.selectById(zzzsProductRecording.getId());
        System.out.println("zzzsCertificate = " + zzzsProductRecording);
        zzzsProductRecording.setExitStatus(ExamineConstant.ExitStatus.NO_EXIT.getCode());
        baseMapper.updateById(zzzsProductRecording);
        ZzzsExamine examine = examineService.getOne(new QueryWrapper<ZzzsExamine>().eq("record_id", zzzsProductRecording.getId())
                .eq("record_type", ExamineConstant.RecordType.PRODUCT_EXIT.getCode()).eq("examine_status", ExamineConstant.StatusEnum.CHECK_STATUS.getCode()));
//        examine.setExamineStatus(ExamineConstant.StatusEnum.SUCCESS_STATUS.getCode());
        examine.setExamineStatus(3);
        examineService.updateById(examine);

    }
//    public void noExit(ZzzsProductRecording zzzsProductRecording) {
//        zzzsProductRecording = baseMapper.selectById(zzzsProductRecording.getId());
//        System.out.println("zzzsCertificate = " + zzzsProductRecording);
//        zzzsProductRecording.setExitStatus(ExamineConstant.ExitStatus.NO_EXIT.getCode());
//        baseMapper.updateById(zzzsProductRecording);
//        ZzzsExamine examine = examineService.getOne(new QueryWrapper<ZzzsExamine>().eq("record_id", zzzsProductRecording.getId())
//                .eq("record_type", ExamineConstant.RecordType.PRODUCT_EXIT.getCode()).eq("examine_status", ExamineConstant.StatusEnum.CHECK_STATUS.getCode()));
//        examine.setExamineStatus(ExamineConstant.StatusEnum.ERROR_STATUS.getCode());
//        examineService.updateById(examine);
//    }

    @Transactional
    @Override
    public void submitRecord(ZzzsProductRecording zzzsProductRecording) {
        zzzsProductRecording.setStatus(ReCordConstant.RecordEnum.RECORD_CHECK.getCode());
        zzzsProductRecording.setIsLogout(ReCordConstant.iterationEnum.LOGOUT_YES.getCode());
        baseMapper.updateById(zzzsProductRecording);
        //分配审批人
        LoginUser userInfo = UserUtils.getUserInfo();
        SysDepart sysDepart = departService.queryCompByOrgCode(userInfo.getOrgCode());
        List<SysDepart> sysDeparts = departService.queryDeptByPid(sysDepart.getId());

        //找出监管部门
        SysDepart sysDepart1 = sysDeparts.stream().filter(item -> {
            return item.getOrgCategory().equals("3");
        }).findAny().get();
        SysUserDepart user = userService.getUserByDeptId(sysDepart1.getId());
        if (user != null) {
            zzzsProductRecording.setApproverId(user.getUserId());
        }

        this.saveOrUpdate(zzzsProductRecording);
        //在审批表中插入记录
        ZzzsExamine zzzsExamine = new ZzzsExamine();
        zzzsExamine.setRecordId(zzzsProductRecording.getId());
        zzzsExamine.setRecordType(ExamineConstant.RecordType.PRODUCT_RECORD.getCode());
        zzzsExamine.setExaminePerson(user.getUserId());
        zzzsExamine.setExamineStatus(ExamineConstant.StatusEnum.CHECK_STATUS.getCode());
        examineService.save(zzzsExamine);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //过期前30分钟基于提醒
        redisTemplate.opsForValue().set(zzzsExamine.getId() + "_" + format.format(new Date()) + "_" + user.getUserId() + "_产品_message", "", 2 * 24 * 60 - 30, TimeUnit.MINUTES);
        redisTemplate.opsForValue().set(zzzsExamine.getId() + "_" + format.format(new Date()) + "_" + user.getUserId() + "_产品_exceed", "", 2, TimeUnit.DAYS);
    }

    @Override
    @Transactional
    public void change(ZzzsProductRecording zzzsProductRecording) {
        //先将上一条备案信息隐藏
        ZzzsProductRecording record = new ZzzsProductRecording();
        record.setId(zzzsProductRecording.getId());
        record.setIsLogout(ReCordConstant.iterationEnum.LOGOUT_NO.getCode());
        int i = baseMapper.updateIsDeleteById(record);
        //再将重新备案的id设置为null
        zzzsProductRecording.setId(null);
        this.submitRecord(zzzsProductRecording);
        //将证书表对应的备案id改成新的备案id
        List<ZzzsCertificate> list = certificateService.lambdaQuery().eq(ZzzsCertificate::getCertificateId, record.getId()).list();
        for (ZzzsCertificate certificate : list) {
            certificate.setCertificateId(zzzsProductRecording.getId());
            certificate.setStatus(CertificateConstant.CertificateStatus.INVALID.getCode());
            certificateService.updateById(certificate);
        }

    }

    @Override
    @Transactional
    public void review(ZzzsProductRecording zzzsProductRecording) {
        //先将上一条备案信息隐藏
        ZzzsProductRecording record = new ZzzsProductRecording();
        record.setId(zzzsProductRecording.getId());
        record.setIsLogout(ReCordConstant.iterationEnum.LOGOUT_NO.getCode());
        System.out.println("record = " + record);
        int i = baseMapper.updateIsDeleteById(record);
        System.out.println("i = " + i);
        //再将重新备案的id设置为null
        zzzsProductRecording.setId(null);
        this.submitRecord(zzzsProductRecording);
        //将证书表对应的备案id改成新的备案id
        ZzzsCertificate certificate = certificateService.getOne(new QueryWrapper<ZzzsCertificate>().eq("certificate_id", record.getId()));
        certificate.setCertificateId(zzzsProductRecording.getId());
        certificate.setStatus(CertificateConstant.CertificateStatus.GIVEN_OUT.getCode());
        certificateService.updateById(certificate);


    }

    @Override
    public ZzzsProductRecording getHaveInfoById(String id) {

        return baseMapper.getHaveInfoById(id);
    }

    @Override
    public Map<String, Object> traceSource(String productId) {

        Map<String, Object> map = new HashMap<>();
        //产品信息
        ZzzsProductRecording productRecording = baseMapper.selectById(productId);
        map.put("productRecording", productRecording);
        String fieldId = productRecording.getFieldId();
        //根据产品信息查出对应的公司介绍信息，
        List<ZzzsBasicInfo> list = basicInfoService.list(new QueryWrapper<ZzzsBasicInfo>()
                .eq("sys_org_code", productRecording.getSysOrgCode()).eq("state", 1));

        map.put("basicInfo", list.size() > 0 ? list : null);
        //查询展示图片信息
        List<ZzzsVisualInformation> visualInformationList = visualInformationService.list(new QueryWrapper<ZzzsVisualInformation>()
                .eq("sys_org_code", productRecording.getSysOrgCode()).eq("state", 1));
        map.put("visualImg", visualInformationList.size() > 0 ? visualInformationList : null);
        //查询播种信息
        List<ZzzsManagementOfSowing> sowingList = sowingService.list(
                getQueryWrapper(ZzzsManagementOfSowing.class, fieldId, 1)
        );
        map.put("sowingList", sowingList.size() > 0 ? sowingList : null);
        //查询施肥信息
        List<ZzzsFertilizationManagement> fertilizationManagementList = fertilizationManagementService.list(
                getQueryWrapper(ZzzsFertilizationManagement.class, fieldId, 1));
        map.put("fertilizationManagementList", fertilizationManagementList.size() > 0 ? fertilizationManagementList : null);
        //打药信息
        List<ZzzsDosingManagement> dosingManagementList = dosingManagementService.list(getQueryWrapper(ZzzsDosingManagement.class, fieldId, 1));
        map.put("dosingManagementList", dosingManagementList.size() > 0 ? dosingManagementList : null);
        //病虫害防治信息
        List<ZzzsPestAndDiseaseControl> diseaseControlList = diseaseControlService.list(getQueryWrapper(ZzzsPestAndDiseaseControl.class, fieldId, 1));
        map.put("diseaseControlList", diseaseControlList.size() > 0 ? diseaseControlList : null);
        //采摘信息
        List<ZzzsManagementOfHarvest> harvestList = harvestService.list(getQueryWrapper(ZzzsManagementOfHarvest.class, fieldId, 1));
        map.put("harvestList", harvestList.size() > 0 ? harvestList : null);


        return map;
    }

    @Override
    public Map<String, Object> retroactiveAccountability(String productId) {
        ZzzsProductRecording productRecording = baseMapper.selectById(productId);
        //找出准出信息
        ZzzsExamine examine = examineService.getOne(new QueryWrapper<ZzzsExamine>()
                .eq("record_type", ExamineConstant.RecordType.PRODUCT_EXIT.getCode())
                .eq("record_id", productId)
                .eq("examine_status", ExamineConstant.StatusEnum.SUCCESS_STATUS.getCode()));
        //找出企业审批信息
        ZzzsRecordEnterprise enterprise = recordEnterpriseService.getOne(new QueryWrapper<ZzzsRecordEnterprise>()
                .eq("sys_org_code", productRecording.getSysOrgCode())
                .eq("status", ReCordConstant.RecordEnum.RECORD_SUCCESS.getCode()));
        //找出产品生产能力备案信息
        ZzzsRecordingOfProductionCapacity capacity = capacityService.getOne(new QueryWrapper<ZzzsRecordingOfProductionCapacity>()
                .eq("product_id", productId)
                .eq("status", ReCordConstant.RecordEnum.RECORD_SUCCESS.getCode()));
        //找出产品供销能力备案信息
        ZzzsRecordOfSupplyAbility supplyAbility = supplyAbilityService.getOne(new QueryWrapper<ZzzsRecordOfSupplyAbility>()
                .eq("product_id", productId)
                .eq("status", ReCordConstant.RecordEnum.RECORD_SUCCESS.getCode()));
        //找出产品备案信息
        ZzzsExamine product = examineService.getOne(new QueryWrapper<ZzzsExamine>()
                .eq("record_type", ExamineConstant.RecordType.PRODUCT_RECORD.getCode())
                .eq("record_id", productId)
                .eq("examine_status", ExamineConstant.StatusEnum.SUCCESS_STATUS.getCode()));
        Map<String, Object> map = new HashMap<>();
        //再找出各自的审批人信息
        if (examine != null) {
            SysUser exitUser = uService.getById(examine.getExaminePerson());
            RetroactiveAccountabilityVo vo = new RetroactiveAccountabilityVo();
            BeanUtils.copyProperties(exitUser, vo);
            vo.setExamineTime(examine.getUpdateTime());
            map.put("exitUser", vo);
        }
        if (enterprise != null) {
            SysUser enterpriseUser = uService.getById(enterprise.getApproverId());
            RetroactiveAccountabilityVo vo = new RetroactiveAccountabilityVo();
            System.out.println("enterpriseUser = " + enterpriseUser);
            BeanUtils.copyProperties(enterpriseUser, vo);
            vo.setExamineTime(enterprise.getUpdateTime());
            map.put("enterpriseUser", vo);
        }
        if (capacity != null) {
            SysUser capacityUser = uService.getById(capacity.getApproverId());
            RetroactiveAccountabilityVo vo = new RetroactiveAccountabilityVo();
            BeanUtils.copyProperties(capacityUser, vo);
            vo.setExamineTime(capacity.getUpdateTime());
            map.put("capacityUser", vo);
        }
        if (supplyAbility != null) {
            SysUser supplyAbilityUser = uService.getById(supplyAbility.getApproverId());
            RetroactiveAccountabilityVo vo = new RetroactiveAccountabilityVo();
            BeanUtils.copyProperties(supplyAbilityUser, vo);
            vo.setExamineTime(supplyAbility.getUpdateTime());
            map.put("supplyAbilityUser", vo);
        }
        if (product != null) {
            SysUser productUser = uService.getById(product.getExaminePerson());
            RetroactiveAccountabilityVo vo = new RetroactiveAccountabilityVo();
            BeanUtils.copyProperties(productUser, vo);
            vo.setExamineTime(product.getUpdateTime());
            map.put("productUser", vo);
        }


        return map;
    }


    public <T> QueryWrapper<T> getQueryWrapper(Class<T> t, String fieldId, Integer status) {

        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("field_id", fieldId).eq("status", status);
        return queryWrapper;
    }
}
